Locating a Service Ad Hoc
A
service consumer can send out WS-Discovery probe messages to locate
available services. The probe query can include compatibility criteria,
such as a service contract or a service scope. Query parameters are
encoded in a FindCriteria object.
There are two types of query criteria:
contract type names – searches for services with endpoints that implement the specified contract names
scope
– searches for services with endpoints that match the specified scope
(scopes are defined in the endpoint’s behavior and several matching
options for complete or partial matches exist)
The DiscoveryClient class provided by WCF manages probes and raises FindProgressChangedEventArgs events when ProbeMatch responses come in:
discoveryClient =
new DiscoveryClient(new UdpDiscoveryEndpoint());
discoveryClient.FindProgressChanged +=
new EventHandler<FindProgressChangedEventArgs>
(OnFindProgressChanged);
discoveryClient.FindCompleted +=
new EventHandler<FindCompletedEventArgs>
(OnFindCompleted);
discoveryClient.FindAsync
(new FindCriteria(typeof(ICustomerService)),
discoveryClient);
Following this, we are submitting an asynchronous discovery query over UDP. ParseResult examines the service contract, scope, and metadata to determine if the responding service meets the requirements:
Example 4.
private void OnFindProgressChanged( object sender, FindProgressChangedEventArgs e) { ParseResult(e.EndpointDiscoveryMetadata); }
|
The DiscoveryClient class also implements a synchronous Find() method that takes a FindCriteria
parameter that specifies query and query completion criteria, such as
the number of responses or the time to wait for responses.
DiscoveryClient also exposes a Resolve() method to locate a replacement for a service that’s been previously available at a known address. Calling Resolve() follows the same pattern as Find().
Sending and Receiving Service Announcements
Services can announce
their availability when they come online or go offline. These
announcements can be received by all services listening for them. You
configure a service to transmit announcements by adding announcementEndpoints to the serviceDiscovery behavior, as shown in Example 6.20. The service then issues announcements to the configured endpoint.
Example 5.
<behavior name="DiscoveryBehavior"> <serviceDiscovery> <announcementEndpoints> <endpoint name="udpEndpointName" kind="udpAnnouncementEndpoint"/> </announcementEndpoints> </serviceDiscovery> </behavior>
|
The standard udpAnnouncementEndpoint
is preconfigured in WCF. Each announcement includes the service
endpoint location and contract, as well as endpoint-specific metadata.
In highly dynamic
environments, service consumers may want to track available services
instead of probing for availability or relying on the discovery proxy.
Probing introduces additional latency and therefore should not occur as
part of the logic that resolves service
locations. Frequent multicast probing further results in unnecessary
network traffic. Instead, a consumer of dynamically available services
can listen for announcement broadcasts and maintain its own list of
services.
Services interested in receiving local UDP discovery announcements must open up a listener on the udpAnnouncementEndpoint endpoint. WCF provides a pre-built AnnouncementService class to handle service announcements. This class can raise the OnOnlineAnnouncement and OnOfflineAnnouncement events to the hosting application.
This example shows a listener configured for announcement services:
Example 6.
<services> ... application service information ...
<service name="AnnouncementListener"> <endpoint kind="udpAnnouncementEndpoint" /> </service> </services>
|
Next, we register events with AnnouncementService:
Example 7.
AnnouncementService announcementService = new AnnouncementService(); announcementService.OnlineAnnouncementReceived += new EventHandler<AnnouncementEventArgs> (this.OnOnlineAnnouncement); announcementService.OfflineAnnouncementReceived += new EventHandler<AnnouncementEventArgs> (this.OnOfflineAnnouncement);
|
The events receive an EndpointDiscoveryMetadata object, just like the response to a discovery probe. A FindCriteria object determines if the metadata matches endpoint requirements. In the following example, we query an EndpointDiscoveryMetadata announcement for compatibility with the ICustomerService contract:
Example 8.
private void OnlineAnnouncement
(object sender, AnnouncementEventArgs e)
{
EndpointDiscoveryMetadata metadata =
e.EndpointDiscoveryMetadata;
FindCriteria criteria =
new FindCriteria(typeof(ICustomerService));
if (criteria.IsMatch(metadata))
{
... further examine endpoint metadata ...
... store endpoint address for service access ...
}